<?php

class PayService extends AbstractService
{

    /**
     * @var PayService
     */
    private static $instance;

    /**
     * Get the instance of PayService.
     *
     * @return PayService
     */
    public static function get()
    {
        if (!self::$instance) {
            self::$instance = new PayService();
        }
        return self::$instance;
    }


    /**
     * Construction.
     */
    protected function __construct()
    {
        parent::__construct();
    }

    /**
     * 处理创建时的逻辑
     *
     * @param int $userId
     * @return void
     */
    public function handleCreate($userId)
    {
        $payment = SzPersister::get()->getVo(null, ModulePaymentConst::ORM_NAME_PAYMENT, $userId);
        if ($payment) {
            return;
        }

        $payment = new ModulePaymentVo($userId, // user id
            0, // bonusMoney
            0, // purchasedMoney
            0, // commodityValue
            true // insert action
        );
        SzPersister::get()->setVo($payment);
    }

    /**
     * 处理登录时的逻辑
     *
     * @param int $userId
     * @return void
     */
    public function handleLogin($userId)
    {
        PlatformService::getPlatformInstanceByUserId($userId)->getMoney($userId);
    }

    /**
     * 提供当前 service 数据
     *
     * @param int $userId
     * @param boolean $visitMode default false
     * @return array(ModulePaymentVo)
     */
    public function info($userId, $visitMode = false)
    {
        $payment = SzPersister::get()->getVo(null, ModulePaymentConst::ORM_NAME_PAYMENT, $userId);
        return array(
            $payment
        );
    }

    /**
     * Update user money count.
     *
     * @param int $userId
     * @param int $money
     * @param ModulePaymentVo $payment default null
     * @param boolean $logCommodityConsume default true, 如果true，记为价值消耗
     * @param int $commodityValue default 0
     * <pre>
     * 当该参数为0
     *      1. money参数为正数，增加的money必定是免费代币，不需要处理价值流转
     *      2. money参数为负数，扣除的money可能为付费代币，根据付费代币数量的扣除量，扣除价值后，并在返回结果中加入扣除的价值，与扣除的付费代币量
     *      3. 判断$logCommodityConsume，如果为true，则记为价值消耗
     * 当该参数小于0
     *      1. 不可能出现的情况，将该参数调整为0
     * 当该参数大于0
     *      1. money参数为正数，增加的money必定为付费代币，并增加外部传入的价值
     *      2. money参数为负数，不可能出现的情况，如果出现，该参数调整为0
     *      3. 判断$logCommodityConsume，如果为true，则修改为false, 记为价值流入，并在外部进行日志采集
     * </pre>
     * @return array(ModulePaymentVo, int, array($entityId => array($count, $commodityValue), ...))
     */
    public function updateMoney($userId, $money, $payment = null, $logCommodityConsume = true, $commodityValue = 0)
    {
        if ($money < 0) {
            NewTaskService::get()->updateProgress($userId,GameConst::TASK_CASH,abs($money));

            TreeService::get()->updateProgress($userId,GameConst::TREE_TASK_USE_CASH,abs($money));

        }
        return PlatformService::getPlatformInstanceByUserId($userId)->updateMoney($userId, $money, $payment, $logCommodityConsume, $commodityValue);
    }

    /**
     * Get user money count.
     *
     * @param int $userId
     * @param ModulePaymentVo $payment default null
     * @return int
     */
    public function getMoney($userId, $payment = null)
    {
        if (is_null($payment)) {
            $payment = SzPersister::get()->getVo(null, ModulePaymentConst::ORM_NAME_PAYMENT, $userId);

            if (is_null($payment)) {
                $this->handleCreate($userId);
                $payment = SzPersister::get()->getVo(null, ModulePaymentConst::ORM_NAME_PAYMENT, $userId);
            }
        }

        return $payment->getMoney();
    }

    /**
     * 完成订单
     *
     * @param string $platform
     * @param array $extra default null
     * @return string
     */
    public function completePaymentOrder($platform, $extra = null)
    {
        $paymentInstance = $this->getPaymentInstance($platform);
        $result = $paymentInstance->completeOrder($extra);

        if (is_array($result)) {
            try {
                /** @var ModulePaymentOrderVo $order */
                list(, $order) = $result;
                $this->postCompletePaymentOrder($order);

                return $paymentInstance->completeOrderReturnValue($result);
            } catch (Exception $e) {
                return $paymentInstance->completeOrderReturnValue($result);
            }
        } else {
            return $paymentInstance->completeOrderReturnValue($result);
        }
    }

    /**
     * 完成订单后续
     *
     * @param ModulePaymentOrderVo $order
     * @return void
     */
    public function postCompletePaymentOrder($order)
    {
        if ($order instanceof ModulePaymentOrderVo && $order->isChanged() && $order->getStatus() == ModulePaymentConst::STATUS_COMPLETED) {
            $userId = $order->getUserId();
            // 增加一个缓存记录最后一个已完成未阅读订单
            SzContextFactory::get()->getStaticCache($userId)->set(GameConst::CACHE_KEY_UNREAD_PAYMENT_ORDER . $userId,
                $order->getOrderId(), SzTime::HOURS24);

            // 数据采集：充值
            StatisticsService::get()->saveLog($userId, GameConst::LOG_TYPE_FB_CREDIT, array(
                'clientData' => array(
                    'tid' => $order->getPlatformToken(),
                    'item' => $order->getPaymentDefId(),
                    'value' => $order->getPrice() * 10,
                )
            ));
        }
    }

    /**
     * 根据平台类型生成 payment 对象
     *
     * @param $platform
     * @return null|PaymentBase
     */
    private static function getPaymentInstance($platform)
    {
        $instance = null;
        switch ($platform) {

        }
        return $instance;
    }

    /**
     * Get payment def info.
     *
     * @param int $userId
     * @param string $paymentDefId
     * @param string $reqSerial
     * @return string $info
     */
    public function getPaymentDefInfo($userId, $paymentDefId, $reqSerial)
    {
        $appConfig = SzConfig::get()->loadAppConfig('app');
        $lang = GameService::get()->getLang($userId);

        SzConfig::get()->setLang($appConfig['LANG']);
        $paymentSetting = SzConfig::get()->loadAppConfig(GameConst::CONFIG_GAME_PAY, $paymentDefId, true);

        $paramUrl = '';
        if ($appConfig['ENV'] == 'DEV') {
            $develop = (SzParam::getReqParam('dev')) ? SzParam::getReqParam('dev') : 'master';
            $paramUrl = '&dev=' . $develop;
        }

        $requestUrl = "https://{$appConfig['WEB_HOST']}/index.php?token=52d0ee3c031dd&user_id={$userId}&act=product&id=$paymentDefId&serial=$reqSerial$paramUrl";

        $icon   = "https://{$appConfig['H5_CLIENT_URL']}/payIcon/{$paymentSetting['resource']}.png";

        $title = GameService::get()->loadLanguageConfig($lang, $paymentSetting['name']);
        $info =
            '<!DOCTYPE html>
<html>
<head prefix=
    "og: http://ogp.me/ns#
    fb: http://ogp.me/ns/fb#
    product: http://ogp.me/ns/product#">
   <meta property="og:type"                content="og:product" />
   <meta property="og:title"               content="' . $title['value'] . '" />
   <meta property="og:image"               content="' . $icon . '" />
   <meta property="og:description"         content="' . $title['value'] . '" />
   <meta property="og:url"                 content="' . $requestUrl . '" />
   <meta property="product:price:amount"   content="' . $paymentSetting['price'] . '"/>
   <meta property="product:price:currency" content="USD"/>
</head>
</html>';
        return $info;
    }
}
